package com.power.sifa.approve.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson2.JSON;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.aventrix.jnanoid.jnanoid.NanoIdUtils;
import com.ding.api.Di_userFeign;
import com.ding.dto.Di_todoDto;
import com.ding.dto.Di_userDto;
import com.ding.model.enumeration.St_pStatus;
import com.plf.common.domain.ResponseDTO;
import com.plf.common.domain.YesNo;
import com.plf.common.utils.StringUtil;
import com.plf.core.base.model.Ha_user;
import com.plf.core.base.service.Ha_userService;
import com.plf.core.common.service.BaseServiceImpl;
import com.power.sifa.approve.dao.Apl_arrive_detailDao;
import com.power.sifa.approve.model.*;
import com.power.sifa.approve.model.enumeration.*;
import com.power.sifa.approve.model.pageInfo.Apl_arrive_detailPageInfo;
import com.power.sifa.approve.model.pojo.vo.DocumentTreeVO;
import com.power.sifa.approve.model.pojo.vo.ReviewDetailVO;
import com.power.sifa.approve.service.*;
import com.power.sifa.base.model.Apl_common_notice;
import com.power.sifa.base.model.RouterParamBO;
import com.power.sifa.base.model.RouterQueryParamBO;
import com.power.sifa.base.model.enumeration.Tp_noticemsg;
import com.power.sifa.base.service.Apl_common_noticeService;
import com.power.sifa.util.VerifyCodeUtil;
import com.power.sifa.util.service.impl.DidiSmsServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 送达记录详情业务层实现
 */
@Service
@Slf4j
public class Apl_arrive_detailServiceImpl extends BaseServiceImpl implements Apl_arrive_detailService {

//    @Resource
//    private Apl_arrive_detailService service;
    @Resource
    private Apl_arrive_detailDao dao;
    @Resource
    private Apl_mainService apl_mainService;
    @Resource
    private Apl_arrive_materialService apl_arrive_materialService;
    @Resource
    private Apl_arrive_personService apl_arrive_personService;
    @Resource
    private Apl_applicantService apl_applicantService;
    @Resource
    private Apl_targetService apl_targetService;
    @Resource
    private Apl_thirdperService apl_thirdperService;
    @Resource
    private Apl_agentService apl_agentService;
    @Resource
    private Aprv_process_materialsService aprv_process_materialsService;
    @Resource
    private Apl_arrive_receiptService apl_arrive_receiptService;
    @Resource
    private Di_userFeign diUserFeign;
    @Resource
    private Ha_userService ha_userService;
    @Resource
    private com.ding.service.Di_todoRemoteService Di_todoRemoteService;
    @Resource
    private BusinessApproveService businessApproveService;

    @Resource
    private Apl_common_noticeService apl_common_noticeService;




    @Value("${sms.path: #{null}}")
    public String path;


    @Value("${sfding.url: #{null}}")
    public String sfdingUrl;

    /**
     * 行政复议赣政通的 路由： /pages/respond/middle?id=111&mattype=6003735&applyid=222
     * id: 赣政通待办todoId
     */
    private static final String router = "/pages/respond/middle?id=${0}&mattype=${1}&applyid=${2}";

    /**
     * 受理科室电话号码
     */
    public static final String acceptPhone = "0791-83884349";
    /**
     * 审理科室的电话号码
     */
    public static final String hearPhone = "0791-83884740";


    @Override
    public Apl_arrive_detail getById(Serializable id) {
        Apl_arrive_detail detail = dao.findById(id).orElse(null);
        if (ObjectUtil.isNotNull(detail)) {
            List<Apl_arrive_material> materials = apl_arrive_materialService.findMaterialsByRecordIds(Arrays.asList(detail.getId()));
            List<Apl_arrive_person> persons = apl_arrive_personService.findPersonByRecordIds(Arrays.asList(detail.getId()));
            detail.setMaterialList(materials.stream().filter(material -> material.getRecordid().equals(detail.getId())).collect(Collectors.toList()));
            detail.setPersonList(persons.stream().filter(person -> person.getRecordid().equals(detail.getId())).collect(Collectors.toList()));
        }
        return detail;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveOrUpdate(Apl_arrive_detail apl_arrive_detail) {
        // save 如果数据库不存在这条数据，就会执行保存（即将这条数据插入到数据库）；如果数据库存在这条数据，就会根据主键去更新这条数据
        if (apl_arrive_detail.getPrimaryKey() != null) {
            Apl_arrive_detail apl_arrive_detailfDb = dao.findById(apl_arrive_detail.getPrimaryKey()).orElse(null);
            if (apl_arrive_detailfDb != null) {
                BeanUtils.copyProperties(apl_arrive_detail, apl_arrive_detailfDb);
                dao.save(apl_arrive_detailfDb);
                return;
            }
        }
        dao.save(apl_arrive_detail);
    }

    @Override
    public void removeById(Serializable id) {
        dao.deleteById(id);
    }

    @Override
    public Page<Apl_arrive_detail> findAll(Apl_arrive_detailPageInfo pageInfo) {
        //排序等定义
        Sort sort;
        if ("asc".equals(pageInfo.getOrder())) {
            sort = Sort.by(Sort.Direction.ASC, pageInfo.getSort());
        } else {
            sort = Sort.by(Sort.Direction.DESC, pageInfo.getSort());
        }
        //分页的定义
        Pageable pageable = PageRequest.of(pageInfo.getPageNumber() <= 1 ? 0 : pageInfo.getPageNumber() - 1, pageInfo.getPageSize(), sort);
        //查询条件
        Specification spec = this.createSpecification(pageInfo);
        return dao.findAll(spec, pageable);
    }

    @Transactional(rollbackFor = Exception.class)
    public void removeByIds(List<Integer> ids) {
        dao.removeByIds(ids);
    }

    @Override
    public List<Apl_arrive_detail> findAll() {
        return dao.findAll();
    }

    @Override
    public void saveAll(List<Apl_arrive_detail> list) {
        dao.saveAll(list);
    }

    @Override
    public List<Apl_arrive_detail> findDetailByApplyIds(List<String> applyIds) {
        List<Apl_arrive_detail> details = dao.findDetailByApplyIds(applyIds);
        if (CollUtil.isNotEmpty(details)) {
            List<String> recordIds = details.stream().map(Apl_arrive_detail::getId).collect(Collectors.toList());
            List<Apl_arrive_material> materials = apl_arrive_materialService.findMaterialsByRecordIds(recordIds);
            List<Apl_arrive_person> persons = apl_arrive_personService.findPersonByRecordIds(recordIds);
            details.forEach(detail -> {
                detail.setMaterialList(materials.stream().filter(material -> material.getRecordid().equals(detail.getId())).collect(Collectors.toList()));
                detail.setPersonList(persons.stream().filter(person -> person.getRecordid().equals(detail.getId())).collect(Collectors.toList()));
            });
            return details;
        }
        return Collections.emptyList();
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveTemp(List<Apl_arrive_detail> details) {
        if (CollectionUtil.isNotEmpty(details)) {
            details.stream().forEach(detail -> {
                // 获取对应的人员数据
                List<Apl_arrive_person> personList = detail.getPersonList();
                if (CollectionUtil.isNotEmpty(personList)) {
                    // 设置对应的值
                    personList.stream().forEach(person -> person.setRecordid(detail.getId()));
                    this.apl_arrive_personService.saveAll(personList);
                }
            });
        }
    }


    /**
     *
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendDiTodo(Apl_main faMainObj, Integer materialType, String userId, String userName) {
        // 查询当前的id的被申请人
        if (ObjectUtil.isNotNull(faMainObj) && StringUtils.isNotEmpty(userId)) {
            // 查询当前的被申请人信息
            List<Apl_target> targetList = apl_targetService.getTargetListByApplyid(faMainObj.getId());
            // 查询当前的系统承办人的信息
            Ha_user haUser = ha_userService.getById(userId);
            if (CollectionUtil.isNotEmpty(targetList) && ObjectUtil.isNotNull(haUser)) {
                List<String> phone = targetList.stream().map(Apl_target::getPhone).distinct().collect(Collectors.toList());
                phone.add(haUser.getMobile());
                phone = phone.stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
                ResponseDTO userResponseDTO = diUserFeign.getUserByPhones(phone);
                if (userResponseDTO.getCode() == 0 && ObjectUtil.isNotNull(userResponseDTO.getData())) {
                    // 查询对应的用户
                    List<Di_userDto> diUserList = JSONArray.parseArray(JSON.toJSONString(userResponseDTO.getData()), Di_userDto.class);
                    if (CollUtil.isNotEmpty(diUserList)) {
                        Di_userDto sendUser = diUserList.stream().filter(el -> el.getMobile().equals(haUser.getMobile())).findAny().orElse(null);
                        List<Di_userDto> receiveUserList = diUserList.stream().filter(el -> !el.getMobile().equals(haUser.getMobile())).collect(Collectors.toList());
                        // 限制数量小于10
                        if (CollectionUtil.isNotEmpty(receiveUserList) && receiveUserList.size() < 10 && ObjectUtil.isNotNull(sendUser)) {
                            // 发送对应消息到赣政通
                            String title = "南昌司法：被申请人待处理";
                            String content = "南昌司法：【" + faMainObj.getAcceptcode() + "】行政复议案件被申请人待处理";
                            receiveUserList.stream().forEach(diUser -> {
                                // 查询当前的被申请人
                                String diId = NanoIdUtils.randomNanoId();
                                String sendUrl = sfdingUrl + "?todoid=" + diId;
                                String routerUrl = router.replace("${0}", diId).replace("${1}", materialType.toString()).replace("${2}", faMainObj.getId());
                                Di_todoDto todoDto = new Di_todoDto().builder().id(diId)
                                        .bt(title).content(content).wh(faMainObj.getAcceptcode()).moduleName("行政复议").action("被申请人处理").urgent("0").important("1")
                                        .sendUserId(sendUser.getId())
                                        .sendUserName(sendUser.getUserName()).sendDeptId(sendUser.getUnitId()).sendDeptName("南昌司法局")
                                        .receiveUserId(diUser.getId()).receiveUserName(diUser.getUserName()).pStatus(St_pStatus.PENDING)
                                        .receiveDeptId(diUser.getUnitId()).receiveDeptName(CollUtil.isNotEmpty(diUser.getDeptList()) ? diUser.getDeptList().get(0).getFullName() : "暂无")
                                        .sendTime(new Date()).url(sendUrl).route(routerUrl).applyid(faMainObj.getId()).build();

                                this.Di_todoRemoteService.afterValidateSendToDo(todoDto);
                                log.info("赣政通发送被申请人待办任务成功 -> {},{},{}", faMainObj.getId(), diUser.getUserName(), materialType);
                            });

                            // 讲数据保存到
                        } else {
                            log.error("赣政通发送被申请人待办失败,赣政通查询发送人和接收人信息为空-> {}", faMainObj.getId());
                        }
                    }
                } else {
                    log.error("赣政通发送被申请人待办失败,获取赣政通用户信息失败 -> {}", faMainObj.getId());
                    log.error("赣政通发送被申请人待办失败,查询接口报错 -> {}", userResponseDTO.getMsg());
                }
            }
        }
    }


    /**
     * 电子送达发送连接
     *
     * @param detail
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendMessage(Apl_arrive_detail detail) {
        List<Apl_arrive_person> personList = detail.getPersonList();
        List<Apl_arrive_material> materialList = detail.getMaterialList();
        if (CollectionUtil.isNotEmpty(personList)) {
            personList.stream().forEach(person -> {
                if (Tp_sendway.ELEC == person.getSendway()) {
                    if (StringUtil.isEmpty(person.getRecipient())) {
                        log.error("送达人姓名不能为空 -> {}", detail.getApplyid());
                        throw new RuntimeException("送达人姓名不能为空");
                    }
                    if (StringUtil.isEmpty(person.getPhone())) {
                        log.error("送达人移动电话不能为空 -> {}", detail.getApplyid());
                        throw new RuntimeException("送达人移动电话不能为空");
                    }
                    if (11 != person.getPhone().length()) {
                        log.error("送达人移动电话格式不正确 -> {}", detail.getApplyid());
                        throw new RuntimeException("送达人移动电话格式不正确");
                    }
                    Apl_main mainObj = this.apl_mainService.getById(detail.getApplyid());
                    String code = VerifyCodeUtil.getVerify();
                    // 生成送达回执id
                    String receiptid = detail.getApplyid() + NanoIdUtils.randomNanoId();
                    // 短信内容访问的前端地址
                    DidiSmsServiceImpl bean = new DidiSmsServiceImpl();
                    // 对应的参数进行设置 对应的字段为用户名称，案号,文件类型，验证码，电话
                    List<String> params = new ArrayList<>();
                    // 送达人
                    params.add(person.getRecipient());
                    // 案号
                    params.add(mainObj.getAcceptcode());
                    List<Tp_procmaterialEnum> procmaterialEnums = new ArrayList<>();
                    if (CollectionUtil.isNotEmpty(materialList)) {
                        materialList.stream().forEach(el -> {
                            procmaterialEnums.add(Tp_procmaterialEnum.getById(el.getMatttype()));
                        });
                    }
                    Set<Integer> materialStages = new HashSet<>();
                    // 是否审理，受理文件都有，部分文件是没有stage字段的，没有需要两个科室电话都加上
                    AtomicReference<Boolean> batchFile = new AtomicReference<>(false);
                    if (CollectionUtil.isNotEmpty(materialList)) {
                        materialList.stream().forEach(el -> {
                            if (ObjectUtil.isNull(el.getStage())) {
                                batchFile.set(true);
                            } else {
                                materialStages.add(el.getStage());
                            }
                        });
                    }
                    String phone;
                    // 若为审理，受理文件都有
                    if (batchFile.get()) {
                        phone = Apl_arrive_detailServiceImpl.acceptPhone + '，' + Apl_arrive_detailServiceImpl.hearPhone;
                    } else {
                        if (materialStages.contains(Tp_stage.ACCEPT) && materialStages.size() == 1) {
                            phone = Apl_arrive_detailServiceImpl.acceptPhone;
                        } else if (!materialStages.contains(Tp_stage.HEAR) && materialStages.size() == 1) {
                            phone = Apl_arrive_detailServiceImpl.hearPhone;
                        } else {
                            phone = Apl_arrive_detailServiceImpl.acceptPhone + '，' + Apl_arrive_detailServiceImpl.hearPhone;
                        }
                    }
                    // 文件类型
                    List<String> materialNameList = new ArrayList<>();
                    if (CollectionUtil.isNotEmpty(procmaterialEnums)) {
                        materialList.stream().forEach(el -> {
                            if (el.getMatttype().equals(Tp_procmaterialEnum.MATER_CUSTOMER.getId())) {
                                materialNameList.add(el.getFile().getFilename());
                            } else {
                                materialNameList.add(Tp_procmaterialEnum.getById(el.getMatttype()).getDesc());
                            }
                        });
                    }
                    params.add(CollectionUtil.isNotEmpty(materialNameList) ? StringUtils.join(materialNameList, "，") : "受送文件");
                    // 签收网址
                    params.add(this.path);
                    // 验证码
                    params.add(code);
                    // 电话
                    params.add(phone);
                    bean.sendTemplate(DidiSmsServiceImpl.tpl_fileaccept, params, person.getPhone());

                    // 2. 存储一条电子送达回执记录
                    // 过期时间为当前的时间加7天工作日
                    Date expiredTime = businessApproveService.getTargetDay(new Date(), 7);
                    Apl_arrive_receipt receiptObj = Apl_arrive_receipt.builder().id(receiptid).applyid(detail.getApplyid())
                            .code(mainObj.getAcceptcode()).verifycode(code).recordid(detail.getId()).sendtime(new Date()).expiredtime(expiredTime)
                            .personid(person.getId()).status(St_receipt.TODELIVER).build();

                    this.apl_arrive_receiptService.saveOrUpdate(receiptObj);
                }
            });
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveSend(List<Apl_arrive_detail> details, String sendUserId, String sendUserName) {
        // 保存人员数据
        if (CollectionUtil.isNotEmpty(details)) {
            details.stream().forEach(detail -> {
                // 获取对应的人员数据
                List<Apl_arrive_person> personList = detail.getPersonList();
                // 获取送达的文件信息
                List<Apl_arrive_material> materialList = detail.getMaterialList();
                if (CollectionUtil.isNotEmpty(personList)) {
                    // 设置对应的值
                    personList.stream().forEach(person -> {
                        person.setRecordid(detail.getId());
                        person.setSendstatus(St_arrive.SENDING);
                        if (person.getSendway().equals(Tp_sendway.POST)) {
                            if (StringUtils.isEmpty(person.getPostcode())) {
                                throw new RuntimeException("邮寄送达，邮寄单号不能为空");
                            }
                        }
                    });
                    this.apl_arrive_personService.saveAll(personList);
                }
            });
        }
        // 修改对应的送达记录数据
        details.stream().forEach(detail -> {
            detail.setOperateid(sendUserId);
            detail.setOpereatename(sendUserName);
            detail.setFinishtime(new Date());
            detail.setSendstatus(YesNo.YES);
        });
        // 保存对应的数据
        this.saveAll(details);
        details.stream().forEach(this::sendMessage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveNewDetail(Apl_arrive_detail detail) {
        // 新数据设置对应值
        detail.setSendstatus(YesNo.NO);
        Date nowTime = new Date();
        detail.setCreatetime(new Date());
        // 默认过期时间设置为7天
        Date warnTime = DateUtil.offsetDay(nowTime, 7);
        detail.setWarntime(warnTime);
        detail.setCustomer(YesNo.YES);

        this.saveOrUpdate(detail);
        // 保存材料和人员信息
        List<Apl_arrive_person> persons = detail.getPersonList();
        persons.stream().forEach(person -> person.setSendstatus(St_arrive.UNDO));
        List<Apl_arrive_material> materials = detail.getMaterialList();
        this.apl_arrive_materialService.saveAll(materials);
        this.apl_arrive_personService.saveAll(persons);

    }

    @Override
    public ReviewDetailVO getReviewDetailByApplyid(String applyid) {
        // 申请人
        List<Apl_applicant> applicantList = apl_applicantService.getApplicantByApplyid(applyid);
        // 委托代理人
        List<Apl_agent> agentList = apl_agentService.getAgentByApplyid(applyid);
        // 被申请人
        List<Apl_target> targetList = apl_targetService.getTargetListByApplyid(applyid);
        // 第三人
        List<Apl_thirdper> thirdperList = apl_thirdperService.getThirdListByApplyid(applyid);
        return ReviewDetailVO.builder().applicantList(applicantList).agenetList(agentList).targetList(targetList)
                .thirdList(thirdperList).build();

    }

    @Override
    public List<DocumentTreeVO> getDocumentTree(String applyid) {
        // 材料文件和系统文书文件
        List<Aprv_process_materials> allMaterials = aprv_process_materialsService.getAllMaterialByApplyId(applyid);
        // 获取基础的树形结构
        List<DocumentTreeVO> rootList = new ArrayList<>();
        DocumentTreeVO root = DocumentTreeVO.getDefaultDocumentList();
        // 对应文件进行过滤，按照所属的环节进行区分，若不在该对应的环节则删除对应的文件
        Map<Integer, List<Aprv_process_materials>> materialsMap = allMaterials.stream().filter(item -> ObjectUtil.isNotNull(item.getStage()))
                .collect(Collectors.groupingBy(Aprv_process_materials::getStage));

        // 获取当前送达记录涉及的材料文件
        List<Apl_arrive_detail> detailList = this.findDetailByApplyIds(Arrays.asList(applyid));
        detailList = detailList.stream().filter(el -> (ObjectUtil.isNotNull(el.getSendstatus())) && el.getSendstatus().equals(YesNo.YES)).collect(Collectors.toList());
        List<String> sendMaterialIdList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(detailList)) {
            List<Apl_arrive_material> materialList = new ArrayList<>();
            detailList.stream().forEach(detail -> materialList.addAll(detail.getMaterialList()));
            sendMaterialIdList = CollectionUtil.isNotEmpty(materialList) ?
                    materialList.stream().map(Apl_arrive_material::getAttachid).distinct().collect(Collectors.toList()) :
                    Collections.emptyList();
        }
        // 对各个环节的文件进行匹配
        for (Integer stage : materialsMap.keySet()) {
            List<Aprv_process_materials> materials = materialsMap.get(stage);
            Tp_stageEnum stageEnum = Tp_stageEnum.getById(stage);
            DocumentTreeVO child = root.getChildren().stream().filter(item -> item.getKey().equals(stageEnum.getKey())).findAny().orElse(null);
            if (ObjectUtil.isNotNull(child)) {
                List<DocumentTreeVO> innerChild = child.getChildren();
                List<String> finalSendMaterialIdList = sendMaterialIdList;
                innerChild.stream().forEach(inner -> {
                    List<DocumentTreeVO> childList = new ArrayList<>();
                    List<Aprv_process_materials> innerMaterials = materials.stream().filter(m -> m.getMattype().equals(Integer.valueOf(inner.getKey()))).collect(Collectors.toList());
                    innerMaterials.stream().forEach(item -> {
                        Boolean isSend = Boolean.FALSE;
                        if (CollectionUtil.isNotEmpty(finalSendMaterialIdList)) {
                            isSend = finalSendMaterialIdList.contains(item.getAttachid());
                        }
                        childList.add(DocumentTreeVO.builder().key(item.getId()).title(item.getFile().getFilename())
                                .level(3).isSend(isSend).document(item).children(null).build());
                    });
                    inner.setChildren(childList);
                });
            }
        }
        // 查询自定义材料，自定义材料没有stage分类
        DocumentTreeVO child = root.getChildren().stream().filter(item -> item.getKey().equals("customer")).findAny().orElse(null);
        if (ObjectUtil.isNotNull(child)) {
            List<DocumentTreeVO> innerChild = child.getChildren();
            List<String> finalSendMaterialIdList = sendMaterialIdList;
            innerChild.stream().forEach(inner -> {
                List<DocumentTreeVO> childList = new ArrayList<>();
                List<Aprv_process_materials> innerMaterials = allMaterials.stream().filter(m -> m.getMattype().equals(Integer.valueOf(inner.getKey()))).collect(Collectors.toList());
                innerMaterials.stream().forEach(item -> {
                    Boolean isSend = Boolean.FALSE;
                    if (CollectionUtil.isNotEmpty(finalSendMaterialIdList)) {
                        isSend = finalSendMaterialIdList.contains(item.getAttachid());
                    }
                    childList.add(DocumentTreeVO.builder().key(item.getId()).title(item.getFile().getFilename())
                            .level(3).isSend(isSend).document(item).children(null).build());
                });
                inner.setChildren(childList);
            });
        }
        // 查询复议监督材料
        DocumentTreeVO superviseChild = root.getChildren().stream().filter(item -> item.getKey().equals("supervise")).findAny().orElse(null);
        if (ObjectUtil.isNotNull(superviseChild)) {
            List<DocumentTreeVO> innerChild = superviseChild.getChildren();
            List<String> finalSendMaterialIdList = sendMaterialIdList;
            innerChild.stream().forEach(inner -> {
                List<DocumentTreeVO> childList = new ArrayList<>();
                List<Aprv_process_materials> innerMaterials = allMaterials.stream().filter(m -> m.getMattype().equals(Integer.valueOf(inner.getKey()))).collect(Collectors.toList());
                innerMaterials.stream().forEach(item -> {
                    Boolean isSend = Boolean.FALSE;
                    if (CollectionUtil.isNotEmpty(finalSendMaterialIdList)) {
                        isSend = finalSendMaterialIdList.contains(item.getAttachid());
                    }
                    childList.add(DocumentTreeVO.builder().key(item.getId()).title(item.getFile().getFilename())
                            .level(3).isSend(isSend).document(item).children(null).build());
                });
                inner.setChildren(childList);
            });
        }
        rootList.add(root);
        return rootList;
    }


    @Override
    public void createSaveNotice(String applyid, String acceptcode, String userid, Integer days, String content, Integer mattype, Integer msgType) {
        Date warntime = DateUtil.offsetDay(new Date(), days);
        Apl_arrive_detail detailObj = Apl_arrive_detail.builder().id(NanoIdUtils.randomNanoId()).applyid(applyid).
                createtime(new Date()).warntime(warntime).noticeperid(userid).customer(YesNo.NO).sendstatus(YesNo.NO).content(content).acceptcode(acceptcode).build();

        // 生成一条材料记录
        List<Aprv_process_materials> materials = aprv_process_materialsService.getAllMaterialByApplyId(applyid);
        List<Apl_arrive_material> arriveMaterials = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(materials)) {
            materials = materials.stream().filter(el -> el.getMattype().equals(mattype) && (el.getSign().equals(Tp_sign.SIGNED)) &&
                    (el.getFile().getFilename().endsWith(".pdf") || el.getFile().getFilename().endsWith(".PDF"))).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(materials)) {
                materials.stream().forEach(item -> {
                    Apl_arrive_material material = Apl_arrive_material.builder().id(NanoIdUtils.randomNanoId()).recordid(detailObj.getId())
                            .attachid(item.getAttachid()).matttype(item.getMattype()).materialid(item.getId())
                            .stage(item.getStage()).build();
                    arriveMaterials.add(material);
                });
            }
        }
        if (CollectionUtil.isNotEmpty(arriveMaterials)) {
            detailObj.setMaterialList(arriveMaterials);
            this.apl_arrive_materialService.saveAll(arriveMaterials);
            this.saveOrUpdate(detailObj);
            if (msgType.equals(Tp_noticemsg.ADMREIVEW_ARRIVE)) {
                createAdmreivewNotice(applyid, detailObj, userid, content, warntime,Tp_noticemsg.ADMREIVEW_ARRIVE);
            } else if (msgType.equals(Tp_noticemsg.SUPERVISE_ARRIVE)) {
                createAdmreivewNotice(applyid, detailObj, userid, content, warntime,Tp_noticemsg.SUPERVISE_ARRIVE);
            }
        }
    }

    /**
     * 行政复议消息通知生成，可跳转路由
     */
    private void createAdmreivewNotice(String applyid, Apl_arrive_detail detailObj, String userid, String content, Date warntime, Integer msgType) {
        String router = "/ArriveInfoAdd/" + applyid;
        String queryUrl = "/ArriveInfo";
        if (msgType.equals(Tp_noticemsg.ADMREIVEW_ARRIVE)) {
            // 跳转到行政复议送达
            router = "/ArriveInfoAdd/" + applyid;
            queryUrl = "/ArriveInfo";
        } else if (msgType.equals(Tp_noticemsg.SUPERVISE_ARRIVE)) {
            // 跳转到复议监督送达
            router = "/SuperviseArriveInfoAdd/" + applyid;
            queryUrl = "/ArriveInfo";
        }
        String queryParamStr = JSON.toJSONString(detailObj);
        RouterParamBO paramBO = new RouterParamBO();
        paramBO.setPath(router);
        RouterQueryParamBO queryParamBO = new RouterQueryParamBO();
        queryParamBO.setUrl(queryUrl);
        queryParamBO.setQueryParam(detailObj);
        paramBO.setQuery(queryParamBO);

        Apl_common_notice notice = Apl_common_notice.builder().id(NanoIdUtils.randomNanoId())
                .createtime(new Date()).warntime(warntime).userid(userid).content(content).msgtype(msgType)
                .router(JSON.toJSONString(paramBO)).build();
        this.apl_common_noticeService.sendMessage(notice);
    }


    @Override
    public List<Apl_arrive_detail> getByUserid(String userid) {
        return this.dao.getByNoticeUserId(userid);
    }

    @Override
    public Apl_arrive_detail getByApplyid(String userid) {
        List<Apl_arrive_detail> details = this.dao.getByApplyid(userid);
        if (CollectionUtil.isNotEmpty(details)) {
            return details.get(0);
        }
        return null;
    }

    /**
     * 根据id删除一条送达记录信息
     *
     * @param id
     * @return
     */
    @Override
    public void deleteDetailById(String id) {
        Apl_arrive_detail detail = this.getById(id);
        if (ObjectUtil.isNotNull(detail)) {
            String detailId = detail.getId();
            // 删除人员和材料信息
            this.apl_arrive_materialService.removeByRecordIds(Collections.singletonList(detailId));
            // 删除人员信息
            this.apl_arrive_personService.removeByRecordIds(Collections.singletonList(detailId));
            // 删除该条记录
            this.removeById(id);
        }
    }
}
